/**
 * Created with IntelliJ IDEA.
 * User: zzl
 * Date: 12-12-14
 * To change this template use File | Settings | File Templates.
 */
(function ($, undefined) {

    /*
     * host: the element dropdown attached to
     * content: the element dropdown shows
     */
    var Dropdown = function (host, options) {
        this.$host = $(host);
        this.options = options;
        this.$content = $(options.content);
        this.$container = $('<div class="dropdown"></div>').appendTo(document.body);
        this.setup();
    };

    var proto = { constructor: Dropdown };
    Dropdown.prototype = proto;

    proto.setup = function () {
        var me = this;
        me.$container.append(me.$content).hide();
        me.$content.show();
        if (me.options.triggerEvent) {
            me.$host.on(me.options.triggerEvent + '.dropdown', function (e) {
                me.host_triggering(e);
            });
        }
//        me.$container.on('hideRequest', function() {
//            me.hide();
//        });
    };

    proto.host_triggering = function (e) {
        var me = this;
        me.show();
    };

    proto.show = function () {
        var me = this;

        //
        var beforeShow = me.options.listeners.beforeShow;
        if (beforeShow) {
            var retval = beforeShow.call(this, me.$host[0]);
            if (retval === false) {
                return;
            }
        }

        //
        var pos = me.$host.offset();
        var hostH = me.$host.outerHeight();
        var hostW = me.$host.outerWidth();
        var viewport = domex.getViewport();

        //measure first?

        var x = pos.left;
        var y = pos.top + hostH + me.options.offsets.y;
        var w = me.$container.outerWidth();
        var h = me.$container.outerHeight();
        if (y + h > viewport.y2) {
            y = pos.top - h - me.options.offsets.y;
        }
        if (y < viewport.y1) {
            y = viewport.y1;
        }
        if (x + w > viewport.x2) {
            x = pos.left + hostW - w;
        }
        if (x < viewport.x1) {
            x = viewport.x1;
        }

        me.$container.css({
            left: x + 'px',
            top: y + 'px'
        });
        me.$container.show();
        me.$container.on('mousedown.dropdown', function (e) {
//            e.stopPropagation();
            me.$host.data('mousedown_host', true);
        });
        $(document).on('mousedown.dropdown', function (e) {
            me.document_mousedown(e);
        });
        $(document).on('mouseup.dropdown', function (e) {
            me.$host.data('mousedown_host', false);
        });
        if (jsex.msie) {
            $(document).on('mousemove.dropdown', function (e) {
                if (e.target.nodeName) {
                    me.lastMousePos = {
                        x: e.pageX,
                        y: e.pageY
                    }
                }
            });
        }
    };

    proto.document_mousedown = function (e) {
        var me = this;
        if (me.$container.containsEvent(e) ||
            me.$host.containsEvent(e) ||
            $(e.target).parents('.nihility:first').length) {
            return;
        }
        if (jsex.msie && !e.target.nodeName) {
            var offset = me.$container.offset();
            var w = me.$container.width();
            var h = me.$container.height();
            var x = me.lastMousePos.x;
            var y = me.lastMousePos.y;
            if (x > offset.left && x < offset.left + w &&
                y > offset.top && y < offset.top + h) {
                return;
            }
        }
        me.hide();
    };

    proto.hide = function () {
        var me = this;

        //
        var beforeHide = me.options.listeners.beforeHide;
        if (beforeHide) {
            var retval = beforeHide.call(this, me.$host[0]);
            if (retval === false) {
                return;
            }
        }

        //
        me.$container.hide();

        //
        me.$container.off('.dropdown');
        $(document).off('.dropdown');
    };

    proto.unload = function () {
        var me = this;
        me.$host.off('.dropdown');
        me.$container.remove();
        me.$host.removeData('dropdown');
    };

    $.fn.dropdown = $.addPluginFn('dropdown', Dropdown, {
        debug: false,
        offsets: {
            x: 0,
            y: 2
        },
        triggerEvent: undefined,
        listeners: {}
    });

})(jQuery);